import { assign, get } from "lodash-es";
import type { INode } from "../lib/types";

// 1 > 2
const ExpReg = /(.*)\s*(>=|<=|==|!=|>|<)\s*(.*)/;
const ForReg = /(.*)\s*in\s*(.*)/;

export function isNumber(val: string) {
    return !isNaN(Number(val));
}

// 计算 表达式 
export function calcExp(expStr: string, inData: any, node: INode | null = null) {
    const exp = expStr.match(ExpReg);
    if (exp) {
        const left = exp[1].trim();
        const right = exp[3].trim();
        const operator = exp[2].trim();
        let leftVal = null;
        let rightVal = null;
        if (node) {
            leftVal = getTreeData(node, inData, left) ?? inData[left] ?? left;
            rightVal = getTreeData(node, inData, right) ?? inData[right] ?? right;
      
        } else {
            leftVal = inData[left] ?? left;
            rightVal = inData[right] ?? right;
        }
        
        if (leftVal && isNumber(leftVal)) {
            leftVal = Number(leftVal);
        }
        if (rightVal && isNumber(rightVal)) {
            rightVal = Number(rightVal);
        }

        if (operator === ">") {
            return leftVal > rightVal;
        }
        if (operator === "<") {
            return leftVal < rightVal;
        }
        if (operator === ">=") {
            return leftVal >= rightVal;
        }
        if (operator === "<=") {
            return leftVal <= rightVal;
        }
        if (operator === "==") {
            return leftVal == rightVal;
        }
        if (operator === "!=") {
            return leftVal != rightVal;
        }
    }
    return false;
}


// for 表达式
export function calcFor(expStr: string, inData: any, node: INode | null = null) {
    const exp = expStr.match(ForReg);
    let outData = [];

    if (exp) {
        const left = exp[1].trim();
        const right = exp[2].trim();
        let rightVal = null;
        let leftVal = null;
   
        if (node) {
            rightVal = getTreeData(node, inData, right) ?? inData[right] ?? right;
            leftVal = getTreeData(node, inData, left) ?? inData[left] ?? left;
        } else {
            rightVal = inData[right] ?? right;
            leftVal = inData[left] ?? left;
        }

    
       
        for (let i = 0; i < rightVal.length; i++) {
            outData.push({
                [left]: rightVal[i]
            });
        }
    }
    return outData;
}

 export function getParentLocalData(node: INode, key: string): any {
    if (node.parent) {
        const val = get(node.parent, "localData." + key, null);
        if (val) {
            return val;
        } else {
            if (node.parent.parent) {
                return getParentLocalData(node.parent, key);
            }
            return null;
        }
    }
    return null;
}


// 获取数据
export function getTreeData(node: INode, inData: any, key: string): any {
    const val = inData[key];

    if (val) {
        return val;
    }

    if (node.localData && node.localData[key]) {
        return node.localData[key];
    }

    let localData = getParentLocalData(node, key);

    if (localData) {
        return localData;
    }

    return val;
}